﻿/********************************************************************
	created:	2010/10/01
	created:	1:10:2010   22:30
	filename: 	f:\CONG DUNG\ExtremeProgramingChallenge\Pathman\Pathman\CSounds.h
	file path:	f:\CONG DUNG\ExtremeProgramingChallenge\Pathman\Pathman
	file base:	CSounds
	file ext:	h
	author:		WaZoombie
	
	purpose:	Class to manage sounds.
*********************************************************************/

#include "CSounds.h"

CSounds::CSounds (HWND hwnd){
	m_hwnd		= hwnd;
	m_device	= -1;
	m_freq		= 48000;
	m_flags		= 0;
	
	init(m_device, m_freq, m_flags);	// Khởi tạo với device mặc định (-1), tần số mẫu chuẩn (48000), không có tham số gì thêm (0)

}

CSounds::~CSounds (){
	map<string, STREAM_NODE>::iterator str_iter = m_sounds.begin();
	while (str_iter != m_sounds.end()){
		// free all streams
		if (str_iter->second.type == STR_MOD){
			BASS_MusicFree(str_iter->second.hStream);
		} else {
			BASS_StreamFree(str_iter->second.hStream);
		}
		str_iter++;
	}
	m_sounds.clear();					// Clear all node
}

bool	CSounds::init (int device, DWORD freqs, DWORD flags){

	// Check BASS version
	if (HIWORD(BASS_GetVersion()) != BASSVERSION){
		MessageBoxA(m_hwnd, "An incorrect version of Bass.dll was loaded !", "Error", MB_OK | MB_ICONERROR);
		return false;
	}

	// Init bass
	if (!BASS_Init(m_device, m_freq, m_flags, m_hwnd, 0)){
		return false;
	}

	return true;
}


bool	CSounds::addFile (STREAM_TYPE type, string name, string filename, DWORD flag){
	if (m_sounds.find(name) == m_sounds.end()){			// The name does not exist
		DWORD		hSound	= NULL;
		if (type == STR_MOD){							// MOD format
			// Loads a MOD music file; MO3 / IT / XM / S3M / MTM / MOD / UMX formats.
			hSound = BASS_MusicLoad(FALSE, filename.c_str(), 0, 0, flag, 0);
			if (hSound){
				m_sounds[name].hStream	= hSound;
				m_sounds[name].type		= type;
				return true;
			} else {
				MessageBoxA(m_hwnd, "Bass load file failed !", "Error", MB_OK | MB_ICONERROR);
				return false;
			}
		} else if (type == STR_MP123_OGG_WAV_AIFF){
			// Creates a sample stream from an MP3, MP2, MP1, OGG, WAV, AIFF formats
			hSound = BASS_StreamCreateFile(FALSE, filename.c_str(), 0, 0, flag);
			if (hSound){
				m_sounds[name].hStream	= hSound;
				m_sounds[name].type		= type;
				return true;
			} else {
				MessageBoxA(m_hwnd, "Bass load file failed !", "Error", MB_OK | MB_ICONERROR);
				return false;
			}
		} else {
			MessageBoxA(m_hwnd, "Unsupported format !", "Info", MB_OK | MB_ICONERROR);
			return false;
		}
	} else {											// The name does exist
		return false;
	}
}

bool	CSounds::remove (string name){
	map<string, STREAM_NODE>::iterator temp = m_sounds.find(name);
	if (temp != m_sounds.end()){			// Sound exist
		// Free sound
		if (temp->second.type == STR_MP123_OGG_WAV_AIFF){
			BASS_StreamFree(temp->second.hStream);
		} else if (temp->second.type == STR_MOD){
			BASS_MusicFree(temp->second.hStream);
		}
		m_sounds.erase(temp);				// Remove node
		return true;
	} else {
		return false;
	}
}

bool CSounds::play (string name, bool restart){
	map<string, STREAM_NODE>::iterator temp = m_sounds.find(name);
	if (temp != m_sounds.end()){
		if (BASS_ChannelPlay(temp->second.hStream, restart)) {
			return true;
		} else {
			return false;
		}
	} else {
		return false;
	}
}

bool CSounds::pause (string name){
	map<string, STREAM_NODE>::iterator temp = m_sounds.find(name);
	if (temp != m_sounds.end()){
		if (BASS_ChannelPause(temp->second.hStream)){
			return true;
		} else {
			return false;
		}
	} else {
		return false;
	}
}

bool	CSounds::stop (string name){
	map<string, STREAM_NODE>::iterator temp = m_sounds.find(name);
	if (temp != m_sounds.end()){
		if (BASS_ChannelStop(temp->second.hStream)){
			return true;
		} else {
			return false;
		}
	} else {
		return false;
	}
}

DWORD	CSounds::getState (string name){
	map<string, STREAM_NODE>::iterator temp = m_sounds.find(name);
	if (temp != m_sounds.end()){
		return BASS_ChannelIsActive(temp->second.hStream);
	} else {
		return NULL;
	}
}

void CSounds::pauseAll (){
	BASS_Pause();
}

void CSounds::stopAll (){
	BASS_Stop();
}

void CSounds::resumeAll (){
	BASS_Start();
}

void CSounds::setGlobalVolume (int val){
	BASS_SetVolume(float(val)/100.0f);
}

void CSounds::setItemVolume (string name, int val){
	map<string, STREAM_NODE>::iterator temp = m_sounds.find(name);
	if (temp != m_sounds.end()){
		BASS_ChannelSetAttribute(temp->second.hStream, BASS_ATTRIB_VOL, float(val)/100.0f);
	}
}